package cn.virens.server.aio.channel.runnable;

import java.nio.ByteBuffer;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.virens.common.RingByteBuffer;
import cn.virens.server.aio.channel.AioChannelSimple;
import cn.virens.server.aio.handler.PacketHandler;
import cn.virens.server.common.ReadPacket;

public class AioChannelReadRunnable implements Runnable {
	private final Logger logger = LoggerFactory.getLogger(getClass());

	private final RingByteBuffer buffer = new RingByteBuffer(10240);

	private final AioChannelSimple channel;

	public AioChannelReadRunnable(AioChannelSimple channel) {
		this.channel = channel;
	}

	public void offer(ByteBuffer other) {
		synchronized (buffer) {
			this.buffer.write(other);
		}
	}

	public void execute() {
		channel.getAcceptHandler().execute(this);
	}

	@Override
	public void run() {
		ReadPacket packet = null;

		while (buffer.length() > 0) {
			// 保证连接还是被打开状态
			if (channel.isRemove()) return;
			if (!channel.isOpen()) return;

			try {
				synchronized (buffer) {
					// 在锁内对数据进行解码 & 获取缓冲区默认值
					int index = buffer.getIndex();
					int length = buffer.getLength();
					int marker = buffer.getMarker();

					// 调用解码器对数据进行解码 & 解码失败就跳出循环解码
					if ((packet = decode(buffer)) == null) {
						this.buffer.setMarker(marker);
						this.buffer.setLength(length);
						this.buffer.setIndex(index);

						return;
					}
				}

				// 解码后过滤能处理的处理器对数据包进行处理
				for (PacketHandler handler : channel.getHandler()) {
					if (handler.can(packet.getCommand())) {
						handler.handle(channel, packet);
					}
				}
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

	private ReadPacket decode(RingByteBuffer buffer) {
		return channel.getAioDecoder().decode(buffer);
	}

}
